package com.employment.config;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics;
import org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.boot.actuate.info.InfoContributor;
import org.springframework.boot.actuate.info.Info;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.HashMap;
import java.util.Map;

/**
 * 虚拟线程监控配置
 * 
 * @author employment
 * @since 2024-01-01
 */
@Configuration
public class VirtualThreadMonitoringConfig {

    /**
     * 配置JVM线程指标监控，包括虚拟线程
     */
    @Bean
    public JvmThreadMetrics jvmThreadMetrics() {
        return new JvmThreadMetrics();
    }

    /**
     * 自定义度量注册器，添加虚拟线程相关指标
     */
    @Bean
    public MeterRegistryCustomizer<MeterRegistry> virtualThreadMetricsCustomizer() {
        return registry -> {
            // 添加虚拟线程计数器
            registry.gauge("jvm.threads.virtual.count", this, VirtualThreadMonitoringConfig::getVirtualThreadCount);
            registry.gauge("jvm.threads.platform.count", this, VirtualThreadMonitoringConfig::getPlatformThreadCount);
        };
    }

    /**
     * 虚拟线程信息贡献者，用于健康检查端点
     */
    @Bean
    public InfoContributor virtualThreadInfoContributor() {
        return new VirtualThreadInfoContributor();
    }

    /**
     * 获取虚拟线程数量
     */
    private Double getVirtualThreadCount() {
        try {
            ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
            // 在JDK 21中，可以通过新的API获取虚拟线程信息
            // 这里先使用总线程数作为示例，实际实现需要JDK 21的新API
            return (double) threadMXBean.getThreadCount();
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * 获取平台线程数量
     */
    private Double getPlatformThreadCount() {
        try {
            ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
            // 实际实现中，需要区分虚拟线程和平台线程
            return (double) threadMXBean.getThreadCount();
        } catch (Exception e) {
            return 0.0;
        }
    }

    /**
     * 虚拟线程信息贡献者实现
     */
    private static class VirtualThreadInfoContributor implements InfoContributor {
        @Override
        public void contribute(Info.Builder builder) {
            try {
                ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
                Map<String, Object> threadInfo = new HashMap<>();
                
                threadInfo.put("totalThreads", threadMXBean.getThreadCount());
                threadInfo.put("peakThreads", threadMXBean.getPeakThreadCount());
                threadInfo.put("daemonThreads", threadMXBean.getDaemonThreadCount());
                
                // JDK 21虚拟线程特定信息
                threadInfo.put("jdkVersion", System.getProperty("java.version"));
                threadInfo.put("virtualThreadsSupported", isVirtualThreadsSupported());
                
                builder.withDetail("threads", threadInfo);
            } catch (Exception e) {
                builder.withDetail("threads", "监控信息获取失败: " + e.getMessage());
            }
        }
        
        private boolean isVirtualThreadsSupported() {
            try {
                // 检查是否支持虚拟线程（JDK 21+）
                String javaVersion = System.getProperty("java.version");
                String[] versionParts = javaVersion.split("\\.");
                int majorVersion = Integer.parseInt(versionParts[0]);
                return majorVersion >= 21;
            } catch (Exception e) {
                return false;
            }
        }
    }
}